package com.inspur.edp.ai.flow.metadata.json;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.inspur.edp.ai.flow.exception.FlowException;
import com.inspur.edp.common.type.utils.JsonPropUtil;
import com.inspur.edp.common.type.utils.JsonSerializeUtil;
import io.iec.edp.caf.commons.utils.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @author lizhaorui
 * @date 2025/9/15
 * @description
 */
public class JsonTypeDeserializerMgr {

    private static volatile JsonTypeDeserializerMgr instance;

    private final Map<String, JsonType> typeMap = new HashMap<>();

    public static JsonTypeDeserializerMgr getInstance() {
        if (instance == null) {
            synchronized (JsonTypeDeserializerMgr.class) {
                if (instance == null) {
                    JsonTypeDeserializerMgr temp = new JsonTypeDeserializerMgr();
                    temp.typeMap.put(JsonStringType.TYPE, new JsonStringType());
                    temp.typeMap.put(JsonBooleanType.TYPE, new JsonBooleanType());
                    temp.typeMap.put(JsonNumberType.TYPE, new JsonNumberType());
                    temp.typeMap.put(JsonObjectType.TYPE, new JsonObjectType());
                    temp.typeMap.put(JsonArrayType.TYPE, new JsonArrayType());
                    instance = temp;
                }
            }
        }
        return instance;
    }

    public static JsonType deserialize(JsonNode jsonObject) {
        if (jsonObject == null) {
            return null;
        }
        if (jsonObject instanceof TextNode) {
            String type = jsonObject.asText();
            JsonType typeTemp = JsonTypeDeserializerMgr.getInstance().typeMap.get(type);
            return typeTemp.newInst();
        } else {
            String expressKind = JsonPropUtil.getPropValueAsString(jsonObject, "type");
            if (StringUtils.isEmpty(expressKind)) {
                return null;
            }
            JsonType typeTemplate = JsonTypeDeserializerMgr.getInstance().typeMap.get(expressKind);
            if (typeTemplate == null) {
                throw new FlowException(String.format("there is no %s jsonType deserializer", expressKind));
            }
            if (!jsonObject.isObject()) {
                throw new FlowException("json node must be object node.");
            }
            return JsonSerializeUtil.toObject(jsonObject, typeTemplate.getClass());
        }
    }


}